package com.easyCms.base.busi;

import com.easyCms.base.busi.vo.AppLoginRequestVO;
import com.easyCms.base.busi.vo.AppResetPasswordVO;
import com.easyCms.base.busi.vo.BaseResponse;
import com.easyCms.base.busi.vo.CrmUserInfoVO;
import com.easyCms.base.common.CodeConst;
import com.easyCms.base.common.RespCode;
import com.easyCms.base.entity.*;
import com.easyCms.base.service.*;
import com.easyCms.base.utils.NumberUtils;
import com.easyCms.base.utils.encrypt.EncodesUtil;
import com.easyCms.base.utils.sms.SmsManageSender;
import com.easyCms.base.utils.time.DateUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;

/**
 * 用户注册等业务相关
 *
 * @author lsquan
 */
@Component
@Transactional
public class RegisterUserBusi {
    private static final Logger logger = LoggerFactory.getLogger(RegisterUserBusi.class);
    @Autowired
    private AppCheckCodeSV appCheckCodeSV;
    @Autowired
    private AppIdentitySV appIdentitySV;
    @Autowired
    private SmsManageSender smsManageSender;
    @Autowired
    private AppOperateLogSV appOperateLogSV;
    @Autowired
    private CrmUserSV crmUserSV;
    @Autowired
    private AppApplyListSV appApplyListSV;
    @Autowired
    private CrmUserAuthSV crmUserAuthSV;

    /**
     * 发送验证码
     *
     * @param result
     * @param phoneNumber
     * @param verificationType
     * @return
     */
    public ResultBean sendSmsCheckCode(ResultBean result, String phoneNumber, int verificationType) {
        try {
            // 1.校验该号码是否已经注册(注册验证码检验账号信息)
            if (CodeConst.CheckCode.REGISTER_USER == verificationType) {
                List<AppIdentity> loginNameList = appIdentitySV.findByLoginName(phoneNumber);
                if (!CollectionUtils.isEmpty(loginNameList)) {
                    result.setCode(RespCode.User_Register.PHONE_HAD_REGISTERED);
                    result.setMsg(RespCode.User_Register.PHONE_HAD_REGISTERED_MESSAGE);
                    return result;
                }
            }
            // 2.生成一个六位随机数
            String randomVerCode = NumberUtils.getRandomVerCode();
            AppCheckCode appCheckCode = new AppCheckCode();
            appCheckCode.setPhoneNumber(phoneNumber);
            appCheckCode.setCreateTime(new Date());
            appCheckCode.setCheckCode(randomVerCode);
            appCheckCode.setCheckCodeType(verificationType);
            appCheckCode.setState(CodeConst.State.STATE_VALID);
            appCheckCode.setExpireDate(NumberUtils.getNextDate(5)); // 有效时间为5分钟
            appCheckCodeSV.save(appCheckCode);
            logger.info(
                    "当前生成的验证码为-----------------" + randomVerCode + "--------失效时间为-----" + NumberUtils.getNextDate(10));
            //
            // Map<String, String> params = new HashMap<String, String>();
            // params.put("smsCheckCode", randomVerCode);
            smsManageSender.sendSms(phoneNumber, "SMS_129759688", randomVerCode);
            result.setCode(RespCode.SUCCESS);
            result.setMsg(RespCode.SUCCESS_MESSAGE);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.setCode(RespCode.FAIL);
            result.setMsg(RespCode.FAIL_MESSAGE);
        }
        return result;
    }

    /**
     * 用户注册
     *
     * @param response
     * @param loginPassword
     * @param userName
     * @param phoneNumber
     * @param checkCode
     * @param checCodeType
     * @param request
     * @return
     */
    public CrmUserInfoVO checkAndSaveUserRegisterData(CrmUserInfoVO response, String loginPassword, String userName,
                                                      String phoneNumber, String checkCode, int checCodeType, HttpServletRequest request) {
        try {
            Date now = new Date();

            // 0.审核单验证(通过电话号码去关联)
            AppApplyList applyApplyListExit = appApplyListSV.findValidByPhoneNumber(phoneNumber);
            if (applyApplyListExit != null) {
                switch (applyApplyListExit.getApplyStatus()) {
                    case 1:
                        response.setCode(RespCode.Apply_List_State.WAIT);
                        response.setMessage(RespCode.Apply_List_State.WAIT_MESSAGE);
                        return response;
                    case 2:
                        response.setCode(RespCode.Apply_List_State.APPLY_SUCCESS);
                        response.setMessage(RespCode.Apply_List_State.APPLY_SUCCESS_MESSAGE);
                        return response;
                    case 3:
                        response.setCode(RespCode.Apply_List_State.APPLY_FAIL);
                        response.setMessage(RespCode.Apply_List_State.APPLY_FAIL_MESSAGE);
                        return response;
                    default:
                        break;
                }
            }

            // 1.校验验证码
            AppCheckCode appVerificationCode = appCheckCodeSV.findByPhoneNumberAndCheckCodeAndCheckCodeType(phoneNumber,
                    checkCode, checCodeType);
            // 1.1验证码是否正确校验
            if (appVerificationCode == null) {
                response.setCode(RespCode.User_Register.VERIFICATIONCODE_ERROR);
                response.setMessage(RespCode.User_Register.VERIFICATIONCODE_ERROR_MESSAGE);
                return response;
            }
            // 1.2是否过期校验
            if (appVerificationCode.getExpireDate().before(now)) {
                response.setCode(RespCode.User_Register.CHECK_SMS_DATE_EXPRIE);
                response.setMessage(RespCode.User_Register.CHECK_SMS_DATE_EXPRIE_MESSAGE);
                return response;
            }

            // 2.校验该号码是否已经注册
            List<AppIdentity> loginNameList = appIdentitySV.findByLoginName(phoneNumber);
            if (!CollectionUtils.isEmpty(loginNameList)) {
                response.setCode(RespCode.User_Register.PHONE_HAD_REGISTERED);
                response.setMessage(RespCode.User_Register.PHONE_HAD_REGISTERED_MESSAGE);
                return response;
            }

            // 3.创建审核单
            AppApplyList appApplyList = new AppApplyList();
            appApplyList.setApplyStatus(RespCode.Apply_List_State.WAIT_TYPE);
            appApplyList.setPhoneNumber(phoneNumber);
            appApplyList.setUserName(userName);
            appApplyList.setPassword(loginPassword);
            appApplyList.setState(CodeConst.State.STATE_VALID);
            appApplyListSV.save(appApplyList);

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            response.setCode(RespCode.FAIL);
            response.setMessage(RespCode.FAIL_MESSAGE);
            return response;
        }
        response.setCode(RespCode.SUCCESS);
        response.setMessage(RespCode.SUCCESS_MESSAGE);
        return response;
    }

    /**
     * app忘记密码（重置密码）
     *
     * @param baseInfo
     * @return
     */
    public BaseResponse appResetPassword(AppResetPasswordVO baseInfo) {
        BaseResponse response = new BaseResponse();
        // 1.校验输入参数
        if (null == baseInfo.getLoginName() || null == baseInfo.getNewPassword() || null == baseInfo.getSmsCheckCode()
                || null == baseInfo.getCheckCodeType()) {
            response.setCode(RespCode.User_Register.INFO_NOTNULL_ERROR);
            response.setMessage(RespCode.User_Register.INFO_NOTNULL_ERROR);
            return response;
        }

        String loginName = baseInfo.getLoginName();
        String newPassword = baseInfo.getNewPassword();
        String verificationCode = baseInfo.getSmsCheckCode();
        String verificationType = baseInfo.getCheckCodeType();
        List<AppIdentity> identityList = appIdentitySV.findByLoginName(loginName);
        // 2.校验账号信息
        // 账号不存在
        if (CollectionUtils.isEmpty(identityList)) {
            response.setCode(RespCode.User_Register.USER_NOT_EXIT);
            response.setMessage(RespCode.User_Register.USER_NOT_EXIT);
            return response;
        }
        AppIdentity identity = identityList.get(0);

        // 3校验验证码是否正确
        // 校验验证码
        AppCheckCode appCheckCode = appCheckCodeSV.findByValidAppCheckCode(loginName, verificationCode,
                Integer.valueOf(verificationType), new Date());
        if (appCheckCode == null) {
            response.setCode(RespCode.User_Register.VERIFICATIONCODE_ERROR);
            response.setMessage(RespCode.User_Register.VERIFICATIONCODE_ERROR_MESSAGE);
            return response;
        }

        // 验证全部通过
        // 修改密码 4.保存AppIdentity
        identity.setPassword(newPassword);
        entryptPassword(identity);
        appIdentitySV.save(identity);

        // 5.修改成功该验证码失效-------------------
        appCheckCode.setState(CodeConst.State.STATE_INVALID);
        appCheckCodeSV.save(appCheckCode);
        response.setCode(RespCode.SUCCESS);
        return response;
    }

    /**
     * app账号登录接口(支持用户名和电话登录)
     *
     * @param response
     * @param appLoginRequestVO
     * @param request
     * @return
     */
    public CrmUserInfoVO appLogin(CrmUserInfoVO response, AppLoginRequestVO appLoginRequestVO,
                                  HttpServletRequest request) {
        try {
            // 1.校验输入参数
            String loginName = appLoginRequestVO.getLoginName();
            String password = appLoginRequestVO.getPassword();

            // 2.1校验用户是否存在
            List<AppIdentity> identityList = appIdentitySV.findByLoginName(loginName);

            AppIdentity identity = identityList.get(0);
            // 4.检验密码是否正确
            if (!checkPassword(identity.getSalt(), password, identity.getPassword())) {
                response.setCode(RespCode.User_Register.PASSWORD_ERROR);
                response.setMessage(RespCode.User_Register.PASSWORD_ERROR_MESSAGE);
                return response;
            }

            if (CollectionUtils.isEmpty(identityList)) {
                // 2.2校验审核单状态
                AppApplyList appApplyListExit = appApplyListSV.findValidByPhoneNumber(loginName);
                if (appApplyListExit == null) {
                    response.setCode(RespCode.User_Register.CRM_USER_NOT_EXIT);
                    response.setMessage(RespCode.User_Register.CRM_USER_NOT_EXIT_MESSAGE);
                    return response;
                } else if (appApplyListExit.getApplyStatus() == 1) {
                    response.setCode(RespCode.Apply_List_State.WAIT);
                    response.setMessage(RespCode.Apply_List_State.WAIT_MESSAGE);
                    return response;
                } else {
                    response.setCode(RespCode.Apply_List_State.APPLY_FAIL);
                    response.setMessage(appApplyListExit.getComment());
                    return response;
                }
            }

            // 5.校验用户是否存在
            CrmUser crmUser = crmUserSV.findByHamiCode(identity.getHamiCode());
            if (crmUser == null) {
                response.setCode(RespCode.User_Register.CRM_USER_NOT_EXIT);
                response.setMessage(RespCode.User_Register.CRM_USER_NOT_EXIT_MESSAGE);
                return response;
            }

            // UUID uid = UUID.randomUUID();
            // String token = uid.toString();
            // appIdentityLoginSV.deleteByIdentityId(identity.getId());
            // 6.保存操作日志
            // AppOperateLog log = new AppOperateLog();
            // log.setIdentiyId(identity.getId());
            // log.setOperationType(RespCode.Operate_Type.USER_LOGIN); // 登录
            // log.setOperationIp(NetworkUtil.getCustIpAddr(request));
            // log.setOperationLog("教学系统-" + loginName + "-" +
            // RespCode.Operate_Type.USER_LOGIN_MESSAGE);
            // log.setCreateTime(new Date());
            // log.setState(CodeConst.State.STATE_VALID);
            // appOperateLogSV.save(log);

            response.setHeadImg(crmUser.getHeadImg());
            response.setHamiCode(crmUser.getHamiCode());

            CrmUserAuth userAuth = crmUserAuthSV.findByHamiCode(crmUser.getHamiCode());
            if (userAuth != null) {
                response.setAuthType(userAuth.getAuthType());
            }
            response.setNick(crmUser.getNick());
            // 返回
            response.setCode(RespCode.SUCCESS);
            response.setMessage(RespCode.SUCCESS_MESSAGE);

            // 需要缓存的数据
            request.getSession().setAttribute("userBaseInfo", response);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return response;
    }

    /**
     * 加密密码
     *
     * @param operator
     */
    public void entryptPassword(AppIdentity operator) {
        byte[] md5 = DigestUtils.md5(operator.getPassword());
        String salt = EncodesUtil.encodeHex(md5);
        operator.setSalt(salt);
        byte[] sha1 = DigestUtils.sha1(salt + operator.getPassword());
        operator.setPassword(EncodesUtil.encodeHex(sha1));
    }

    /**
     * 验证密码
     *
     * @param salt
     * @param password
     * @param encodePassword
     * @return
     */
    public Boolean checkPassword(String salt, String password, String encodePassword) {
        byte[] sha1 = DigestUtils.sha1(salt + password);
        if (EncodesUtil.encodeHex(sha1).equals(encodePassword)) {
            return true;
        }
        return false;
    }

    /**
     * 获取用户唯一号
     *
     * @param date
     * @return
     */
    public String getIdentityCode(Date date) {
        return DateUtils.getEvenTime(date) + NumberUtils.getRandomVerCode();
    }

    /**
     * session查询
     *
     * @param querySession
     * @return
     */
    public ResultBean<Object> querySession(String querySession, HttpServletRequest request,
                                           ResultBean<Object> resultBean) {
        if (StringUtils.isBlank(querySession)) {
            resultBean.setCode(ResultBean.FAIL);
            resultBean.setCode("查询参数为空");
            return resultBean;
        }
        HttpSession session = request.getSession();
        if (session.getAttribute(querySession) != null) {
            resultBean.setData(session.getAttribute(querySession));
            resultBean.setCode(ResultBean.SUCCESS);
        } else {
            resultBean.setCode(ResultBean.FAIL);
            resultBean.setData(null);
        }
        return resultBean;
    }

    /**
     * 删除用户缓存
     *
     * @param request
     */
    public void deleteUserSession(HttpServletRequest request) {
        HttpSession session = request.getSession();
        session.removeAttribute("userBaseInfo");
    }

    /**
     * 创建管理员用户
     *
     * @param response
     * @param loginPassword
     * @param userName
     * @param phoneNumber
     * @param request
     * @return
     */
    public ResultBean createAdminUser(ResultBean response, String loginPassword, String userName, String phoneNumber,
                                      HttpServletRequest request) {
        try {
            Date now = new Date();
            // 2.校验该号码是否已经注册
            List<AppIdentity> loginNameList = appIdentitySV.findByLoginName(phoneNumber);
            if (!CollectionUtils.isEmpty(loginNameList)) {
                response.setCode(RespCode.User_Register.PHONE_HAD_REGISTERED);
                response.setMsg(RespCode.User_Register.PHONE_HAD_REGISTERED_MESSAGE);
                return response;
            }

            // 1.保存AppIdentity帐号
            AppIdentity appIdentity = new AppIdentity();
            appIdentity.setValidDate(now);
            appIdentity.setLoginName(phoneNumber);
            appIdentity.setPassword(loginPassword);
            appIdentity.setState(CodeConst.State.STATE_VALID);
            appIdentity.setCreateTime(now);
            appIdentity.setHamiCode(getIdentityCode(now));
            entryptPassword(appIdentity);
            AppIdentity identity = appIdentitySV.save(appIdentity);

            // 4.创建用户
            CrmUser crmUser = new CrmUser();
            crmUser.setHamiCode(appIdentity.getHamiCode());
            crmUser.setUserName(userName);
            crmUser.setPhoneNumber(phoneNumber);
            crmUser.setNick(userName);// 默认昵称
            crmUser.setHeadImg(
                    "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3965109217,1887678806&fm=27&gp=0.jpg");// 默认头像
            crmUser.setState(CodeConst.State.STATE_VALID);
            crmUserSV.save(crmUser);
            CrmUserAuth crmUserAuth = new CrmUserAuth();
            crmUserAuth.setHamiCode(appIdentity.getHamiCode());
            crmUserAuth.setAuthType(CodeConst.USER_AUTH.MANAGER);
            crmUserAuth.setState(CodeConst.State.STATE_VALID);
            crmUserAuthSV.save(crmUserAuth);
            response.setCode(ResultBean.SUCCESS);
            return response;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }

}
